Datum jaccard_index(PG_FUNCTION_ARGS)
{
	text *str_01 = PG_GETARG_DATUM(0);
	text *txt_02 = PG_GETARG_DATUM(1);
	char *a = VARDATA_ANY(str_01), *b = VARDATA_ANY(txt_02);
	int m = VARSIZE_ANY_EXHDR(str_01), n = VARSIZE_ANY_EXHDR(txt_02);
	float4 result = 1;
	SBTreeNode *tree = NULL, *tmp;
	char valid;
	int bigram = ((int)'$') << 8 | (int)a[0];
	int unionset, intersection;
	tmp = insert(&tree, bigram, &valid);
	tmp->dt |= (char)1;
	for (int i = 1; i < m; i++)
	{
		bigram = ((bigram << 8) & 0xff00) | (int)a[i];
		tmp = insert(&tree, bigram, &valid);
		tmp->dt |= (char)1;
	}
	bigram = ((bigram << 8) & 0xff00) | ((int)'$');
	tmp = insert(&tree, bigram, &valid);
	tmp->dt |= (char)1;

	bigram = ((int)'$') << 8 | (int)b[0];
	tmp = insert(&tree, bigram, &valid);
	tmp->dt |= (char)2;
	for (int i = 1; i < n; i++)
	{
		bigram = ((bigram << 8) & 0xff00) | (int)b[i];
		tmp = insert(&tree, bigram, &valid);
		tmp->dt |= (char)2;
	}
	bigram = ((bigram << 8) & 0xff00) | ((int)'$');
	tmp = insert(&tree, bigram, &valid);
	tmp->dt |= (char)2;
	unionset = getSize(tree);
	intersection = getValueCount(tree, (char)3);
	freeTree(tree);
	result = (float4)intersection / (float4)unionset;
	PG_RETURN_FLOAT4(result);
}
